package web.xmlReader;

import java.io.IOException;

import Error.Error;
import IO.Log;

import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import web.rssReader.RssReaderInterface;

import data.Episode;
import data.Show;

public class TvRageXmlReader extends RssReaderInterface
{

	/**
	 * List of seasons for a given show.
	 */
	private int showId;
	
	/**
	 * Constructor
	 * @param urlString - String url to pull the xml data from.
	 * @throws SAXException
	 * @throws IOException
	 * @throws ParserConfigurationException
	 */
	public TvRageXmlReader(String showName)
	{
		showName.replace(' ', '-').toLowerCase();
		
		this.showName = showName;
		this.showId = this.getShowId(showName);
		this.stringURL = "http://tvrage.com/feeds/full_show_info.php?sid="+showId;
		this.connect();
		
		
	}
	
	/**
	 * Return's the season given a season number.
	 * @param seasonNum - The season to return
	 * @return - NodeList of the episodes in that season.
	 */
	public NodeList getSeasonList(int seasonNum, NodeList seasonNodes)
	{
		NodeList returnNodeList = null;
		for(int i=0; i< seasonNodes.getLength(); i++)
		{
			Node n = seasonNodes.item(i);
			if(seasonNum == Integer.parseInt(n.getAttributes().getNamedItem("no").getNodeValue()))
			{
				returnNodeList = n.getChildNodes();
			}
		}
		return returnNodeList;
	}
	
	/**
	 * Create's a show and returns it.
	 */
	public Show getShow()
	{
		this.connect();
		Show show = new Show(showName);
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		dbf.setValidating(false);
		try
		{
			dbf.setFeature("http://xml.org/sax/features/namespaces", false);
			dbf.setFeature("http://xml.org/sax/features/validation", false);
			dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
			dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		DocumentBuilder db = null;
		try 
		{
			db = dbf.newDocumentBuilder();
		} 
		catch (ParserConfigurationException e) 
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Document doc = null;
		try 
		{
			doc = db.parse(url.openStream());
		} 
		catch (SAXException e) 
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) 
		{
			// TODO Auto-generated catch block
			Error.report(21);
			return show;
		}
		
		NodeList seasonNodes = null;
		if(doc != null)
		{
			doc.getDocumentElement().normalize();
			seasonNodes = doc.getElementsByTagName("Season");
		}
		for(int i=1; i<seasonNodes.getLength()+1; i++) //Season Nodes + 1 to compensate for array. AKA season 1 is actually array[0], season 2 is array[1], etc
		{
			NodeList n = getSeasonList(i, seasonNodes);
			for(int j = 0; j<n.getLength();j++)
			{
				
				Node n1 = n.item(j);
				if(n1.getNodeType() == Element.ELEMENT_NODE)
				{
					int epNum = Integer.parseInt(getElementValue((Element)n1, "seasonnum"));
					String epTitle = getElementValue((Element)n1, "title");
					String torrentUrl = null;
					String description = null; 
					String airDate = getElementValue((Element)n1, "airdate");	
					
					SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy-MM-dd" );
					Date date = new Date();
					try {
						date = dateFormat.parse( airDate );
					} catch (ParseException e) {
						Log.printErrorln("Date-parse fail for RvRageXmlReader");
					}
					
					
					Episode e = new Episode(epNum, epTitle, torrentUrl, description,date);						
					show.addEpisode(e, i);
				}
			}
		}
		return show;
	}

	/**
	 * Returns the showId for the given show title. 
	 * @param showName - Title for the show.
	 * @return integer of the showid or -1 if error;
	 * @throws SAXException
	 * @throws IOException
	 * @throws ParserConfigurationException
	 */
	private int getShowId(String showName)
	{
		/*
		 * FIX NEEDED, assumes first element is correct!
		 */
		this.showName = showName;
		showName = showName.replaceAll(" ", "%20");
		URL url = null;
		try {
			url = new URL("http://www.tvrage.com/feeds/search.php?show="+showName);
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = null;
		try {
			db = dbf.newDocumentBuilder();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Document doc = null;
		try {
			doc = db.parse(url.openStream());
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			Error.report(21);
			return -1;
		}
		doc.getDocumentElement().normalize();
		NodeList showList = doc.getElementsByTagName("show");
		Node show = showList.item(0);
		return Integer.parseInt(getElementValue((Element)show, "showid"));
	}
	//Password:c6jYRbvYKuKGRweThKEu
}
